package cz.moglum.bloodb.client.objects;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

import cz.moglum.bloodb.client.RPCObjectFactoryService;
import cz.moglum.bloodb.client.RPCObjectFactoryServiceAsync;
import cz.moglum.bloodb.client.i.ICollectionListener;
import cz.moglum.bloodb.client.i.IObjectFactoryListener;
import cz.moglum.bloodb.client.i.IObjectListener;

/**
 * Manages retrieving and saving of all BaseObject children via RPC
 */
public class RPCObjectFactory {

	// TeamObject DAO
	private RPCObjectDAO teamDAO = new RPCObjectDAO("Team");
	// PlayerObject DAO
	private RPCObjectDAO playerDAO = new RPCObjectDAO("Player");

	// TODO add other DAOs - player, user, etc..

	/**
	 * Returns the Team Database Access Object
	 * 
	 * @return Team Database Access Object
	 */
	public RPCObjectDAO getTeamDAO() {
		return teamDAO;
	}
	
	/**
	 * Returns the Player Database Access Object
	 * 
	 * @return Player Database Access Object
	 */
	public RPCObjectDAO getPlayerDAO() {
		return playerDAO;
	}
	
	// TODO getters for other Object DAOs

	void setListener(IObjectFactoryListener listener) {
		// TODO wtf??
		return;
	}

	// RPC service
	private RPCObjectFactoryServiceAsync service;

	public RPCObjectFactory(String url) {
		service = (RPCObjectFactoryServiceAsync) GWT
				.create(RPCObjectFactoryService.class);
		ServiceDefTarget endpoint = (ServiceDefTarget) service;
		endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + url);
	}

	// TODO doc
	protected class CollectionCallback implements AsyncCallback {
		private ICollectionListener handler;

		public CollectionCallback(ICollectionListener handler) {
			this.handler = handler;
		}

		public void onFailure(Throwable exception) {
			GWT.log("error", exception);
		}

		public void onSuccess(Object result) {
			handler.onCollection((List) result);
		}
	}

	// TODO doc
	protected class ObjectCallback implements AsyncCallback {
		private IObjectListener handler;

		public ObjectCallback(IObjectListener handler) {
			this.handler = handler;
		}

		public void onFailure(Throwable exception) {
			GWT.log("error", exception);
		}

		public void onSuccess(Object result) {
			handler.onObject((BaseObject) result);
		}
	}

	/**
	 * Database Access Object for accessing children of BaseObject via RPC
	 * 
	 * @author Vojtech.Polak
	 * 
	 */
	public class RPCObjectDAO {

		// nahradit ENUMem?
		private final String type;

		public RPCObjectDAO(String type) {
			this.type = type;
		}

		public void getAll(ICollectionListener listener) {
			service.getAll(type, new CollectionCallback(listener));
		}

		public void getById(String id, IObjectListener listener) {
			service.getById(type, id, new ObjectCallback(listener));
		}
	}
}
